from __future__ import annotations

from dataclasses import dataclass
from typing import Literal, Optional

from gssgca.core.standard_loader import provider


@dataclass
class CablewayScheme:
    main_rope_diameter_mm: int
    main_rope_breaking_kN: float
    safety_factor: float
    max_payload_kN: float
    recommend_carriage_weight_kN: float
    note: str


def select_cableway(
    span_m: float,
    payload_kN: float,
    terrain_category: Literal["plain", "hills", "mountain"] = "mountain",
    min_safety_factor: float = 2.5,
    rope_catalog_key: str = "wire_ropes",
) -> CablewayScheme:
    """索道主绳选型（施工牵引/起重简化模型）。

    思路：
    1. 依据跨距与地形类别估算主绳最大水平张力 T_h ≈ α × (荷载 + 自重)
    2. 在型录中选择破断拉力 ≥ min_safety_factor × T_h 的最小直径主绳

    参考：Q/GDW 1799、JGJ 130 等工程经验参量（本函数为工程前期估算用）。
    """

    terrain_alpha = {"plain": 1.6, "hills": 1.8, "mountain": 2.0}[terrain_category]
    catalog = provider.rope_catalog().get(rope_catalog_key, [])
    if not catalog:
        catalog = provider.rope_catalog().get("wire_ropes", [])

    # 估算主绳张力（极简化）：T ≈ α × (有效荷载)
    # 考虑跨距增加带来的弧垂控制张力提升，加入跨距修正 β
    beta = 1.0 + max(0.0, span_m - 300.0) / 600.0  # 300m 基准后线性上浮
    design_tension = terrain_alpha * beta * payload_kN

    selected: Optional[dict] = None
    for item in sorted(catalog, key=lambda x: x.get("breaking_kN", 0.0)):
        if float(item.get("breaking_kN", 0.0)) >= min_safety_factor * design_tension:
            selected = item
            break

    if not selected:
        # 选不到就取最大规格，提示复核
        selected = max(catalog, key=lambda x: x.get("breaking_kN", 0.0))
        note = "未满足安全系数，已取最大规格，需详细校核"
    else:
        note = "满足估算安全系数，建议进行详细建模校核"

    safety_factor = float(selected["breaking_kN"]) / max(1e-6, design_tension)
    recommend_carriage = max(0.1 * payload_kN, 5.0)  # 建议小车自重经验值
    return CablewayScheme(
        main_rope_diameter_mm=int(selected["diameter_mm"]),
        main_rope_breaking_kN=float(selected["breaking_kN"]),
        safety_factor=safety_factor,
        max_payload_kN=payload_kN,
        recommend_carriage_weight_kN=recommend_carriage,
        note=note,
    )


